package com.xcity.game.equip.template;

import java.util.ArrayList;
import java.util.List;

import com.xcity.game.combat.attr.CombatAttribute;
import com.xcity.game.combat.attr.CombatAttributeType;
import com.xcity.game.equip.EquipPosition;
import com.xcity.game.equip.EquipQuality;

import naga.x.common.Interval;
import naga.x.game.template.Template;
import naga.x.game.template.TemplateException;
import naga.x.game.template.annotation.Excel;
import naga.x.util.CommonUtils;

/**
 * 装备数值模板
 * @author yang.li
 *
 */
@Excel(value = "equip.xlsx", sheet = 1)
public class EquipDataTemplate extends Template {

	/** 装备品质（0=D，1=C，2=B，3=A，4=AA，5=AAA，6=S） */
	protected EquipQuality quality;

	/** 装备部位(0=衣服，1=手包，2=手表，3=鞋子) */
	protected EquipPosition pos;

	/** 攻击 */
	protected float attackPower;

	/** 技能攻击 */
	protected float magicPower;

	/** 防御 */
	protected float defense;

	/** 技能防御 */
	protected float magicDefense;

	/** 暴击 */
	protected float crit;

	/** 韧性 */
	protected float avoidCrit;

	/** 生命值 */
	protected float hp;

	/** 出手速度 */
	protected float attackSpeed;
	
//	/** 暴击伤害 */
//	protected float critDamage;
	
	//---v2---
	/** 物攻命中 */
	protected float hitRate;
	
	/** 法攻命中 */
	protected float magicHitRate;
	
	/** 闪避 */
	protected float dodge;
	//---v2---
	
	protected List<Weight> weights;
	public static class Weight implements Interval {
		public int weightStart, weight;
		public CombatAttributeType type; // 战斗属性类型
		@Override
		public int getMinVal() {
			return weightStart;
		}
		@Override
		public int getMaxVal() {
			return weight;
		}
	}

	public EquipQuality getQuality() {
		return quality;
	}

	public void setQuality(EquipQuality quality) {
		this.quality = quality;
	}

	public EquipPosition getPos() {
		return pos;
	}

	public void setPos(EquipPosition pos) {
		this.pos = pos;
	}

	public float getAttackPower() {
		return attackPower;
	}

	public void setAttackPower(float attackPower) {
		this.attackPower = attackPower;
	}

	public float getMagicPower() {
		return magicPower;
	}

	public void setMagicPower(float magicPower) {
		this.magicPower = magicPower;
	}

	public float getDefense() {
		return defense;
	}

	public void setDefense(float defense) {
		this.defense = defense;
	}

	public float getMagicDefense() {
		return magicDefense;
	}

	public void setMagicDefense(float magicDefense) {
		this.magicDefense = magicDefense;
	}

	public float getCrit() {
		return crit;
	}

	public void setCrit(float crit) {
		this.crit = crit;
	}

	public float getAvoidCrit() {
		return avoidCrit;
	}

	public void setAvoidCrit(float avoidCrit) {
		this.avoidCrit = avoidCrit;
	}

	public float getHp() {
		return hp;
	}

	public void setHp(float hp) {
		this.hp = hp;
	}

	public float getAttackSpeed() {
		return attackSpeed;
	}

	public void setAttackSpeed(float attackSpeed) {
		this.attackSpeed = attackSpeed;
	}

//	public float getCritDamage() {
//		return critDamage;
//	}
//
//	public void setCritDamage(float critDamage) {
//		this.critDamage = critDamage;
//	}
	
	public float getHitRate() {
		return hitRate;
	}

	public void setHitRate(float hitRate) {
		this.hitRate = hitRate;
	}

	public float getMagicHitRate() {
		return magicHitRate;
	}

	public void setMagicHitRate(float magicHitRate) {
		this.magicHitRate = magicHitRate;
	}

	public float getDodge() {
		return dodge;
	}

	public void setDodge(float dodge) {
		this.dodge = dodge;
	}
	
	public void setWeights(List<Weight> weights) {
		this.weights = weights;
	}

	public float getValue(CombatAttributeType type) {
		switch (type) {
			/** 普攻 */
			case ATTACK_POWER:
				return attackPower;
			/** 法攻 */
			case MAGIC_POWER:
				return magicPower;
			/** 普防 */
			case DEFENSE:
				return defense;
			/** 法防 */
			case MAGIC_DEFENSE:
				return magicDefense;
			/** 暴击 */
			case CRIT:
				return crit;
			/** 韧性 */
			case AVOID_CRIT:
				return avoidCrit;
			/** 生命值 */
			case HP:
				return hp;
			/** 出手速度 */
			case ATTACK_SPEED:
				return attackSpeed;
//			/** 暴击伤害 */
//			case CRIT_DAMAGE:
//				return critDamage;
			/** 闪避 */
			case DODGE:
				return dodge;
			/** 物攻命中 */
			case HIT_RATE:
				return hitRate;
			/** 法攻命中 */
			case MAGIC_HIT_RATE:
				return magicHitRate;
			default:
				return 0f;
		}
	}
	
	public List<CombatAttribute> generate(int n) {
		List<Weight> weights = deepCopy(this.weights);
		CommonUtils.shuffle(weights);
		if (n < weights.size()) {
			weights = weights.subList(0, n);
		} else {
			n = weights.size();
		}
		List<CombatAttribute> attrs = new ArrayList<CombatAttribute>(n);
		int weight = 0;
		for (int i = 0; i < n; i++) {
			Weight w = weights.get(i);
			w.weightStart = weight;
			weight += w.weight;
			w.weight = weight;
		}
		// 根据权重随机出主属性
		Weight main = CommonUtils.findInterval(weights, CommonUtils.randomInt(weight));
		attrs.add(new CombatAttribute(main.type, getValue(main.type)));
		// 必出物防、法防
		float defense = getValue(CombatAttributeType.DEFENSE);
		if (defense > 0f) {
			attrs.add(new CombatAttribute(CombatAttributeType.DEFENSE, defense));
		}
		float magicDefense = getValue(CombatAttributeType.MAGIC_DEFENSE);
		if (magicDefense > 0f) {
			attrs.add(new CombatAttribute(CombatAttributeType.MAGIC_DEFENSE, magicDefense));
		}
		for (int i = 0; i < n; i++) {
			if (attrs.size() >= n) {
				break;
			}
			Weight w = weights.get(i);
			if (w != main) {
				attrs.add(new CombatAttribute(w.type, getValue(w.type)));
			}
		}
		return attrs;
	}
	
	static List<Weight> deepCopy(List<Weight> list) {
		List<Weight> ret = new ArrayList<Weight>(list.size());
		for (int i = 0; i < list.size(); i++) {
			Weight ref = list.get(i);
			Weight dup = new Weight();
			dup.weightStart = ref.weightStart;
			dup.weight = ref.weight;
			dup.type = ref.type;
			ret.add(dup);
		}
		return ret;
	}

	@Override
	public void validate() throws TemplateException {
	}

	@Override
	public String toString() {
		return null;
	}
	
}
